﻿' ProductData.cs
' compile with: /doc:ProductData.xml
' <copyright>Copyright (c) Microsoft Corporation. All rights reserved.
' </copyright>
' <summary>This file contains the class that stores the product data
' represented by the shapes in the Visio drawing.</summary>

Imports System
Imports System.Diagnostics



''' <summary>The ProductData class handles the product data
''' information.</summary>
Public Class ProductData
    Implements IDisposable

    ''' <summary>The InvalidProductId constant is used to provide a
    ''' consistent value to be assigned to a product ID to flag that the
    ''' value is not valid.</summary>
    Public Const InvalidProductId As Integer = -1

    ''' <summary>The product ID xml element contains an integer that
    ''' uniquely identifies the product.</summary>
    Public Const ProductIdColumnName As String = "ProductID"

    ''' <summary>The range name xml element identifies the high-level
    ''' catagory of the product.</summary>
    Public Const RangeColumnName As String = "RangeName"

    ''' <summary>The description xlm element describes the product.
    ''' </summary>
    Public Const DescriptionColumnName As String = "ProductDescription"

    ''' <summary>The type description xml element describes the type
    ''' of the product.</summary>
    Public Const TypeDescriptionColumnName As String = "TypeDescription"

    ''' <summary>The cost price xml element contains the cost of producing
    ''' the product.</summary>
    Public Const CostPriceColumnName As String = "CostPrice"

    ''' <summary>The wholesale price xml element contains the wholesale
    ''' price of the product.</summary>
    Public Const WholesalePriceColumnName As String = "WholesalePrice"

    ''' <summary>The retail price xml element contains the retail price
    ''' of the product.</summary>
    Public Const RetailPriceColumnName As String = "RetailPrice"

    ''' <summary>The labor hours xml element contains the number of labor
    ''' hours needed to produce the product.</summary>
    Public Const LaborHoursColumnName As String = "LaborHours"

    ''' <summary>The quantity column contains the number of instances of
    ''' the product currently on the drawing surface.</summary>
    Public Const QuantityColumnName As String = "Quantity"

    ''' <summary>A data set is used to store the product information data
    ''' while the application is running.</summary>
    Private productDataSet As System.Data.DataSet

    ''' <summary>The local product data class.</summary>
    Private productDataSource As ProductDataSource

    ''' <summary>Keeps the object from being disposed multiple times.</summary>
    Private disposed As Boolean

    ''' <summary>The ProductDataTable method gets the table
    ''' with the product information from the product data set.
    ''' </summary>
    ''' <returns>The table with the product information if the data set
    ''' is valid. If there is no table, null is returned.</returns>
    Public ReadOnly Property ProductDataTable() As System.Data.DataTable

        Get

            Dim dataTable As System.Data.DataTable = Nothing

            If (productDataSet IsNot Nothing) AndAlso (productDataSet.Tables.Count > 0) Then

                ' There is only one table to return.
                dataTable = productDataSet.Tables(0)
            End If

            Return dataTable
        End Get
    End Property

    ''' <summary>The default ProductData constructor.</summary>
    Public Sub New()

        Try

            productDataSource = New ProductDataSource()



            ' Read the xml data file.
            Dim dataFilename As String

            dataFilename = Utility.GetResourceString(Strings.ProductDataFilename)

            productDataSource.ReadProductData(dataFilename)

            Dim intCt As Int32 = productDataSource.GetProductDataTable.Rows.Count

            Dim strTest As String = ""



        Catch ex As Exception

            Dim errWin As ErrorWindow = New ErrorWindow("new productdata", ex)
            errWin.ShowDialog()

        End Try
    End Sub

    ''' <summary>The GetRetailPrice method gets the retail price
    ''' for the specified product.</summary>
    ''' <param name="productId">The ID of the product to get the
    ''' retail price for.</param>
    ''' <returns>The retail price. If there is an error
    ''' the returned price is 0.</returns>
    Public Function GetRetailPrice(ByVal productId As Integer) As Decimal

        Dim retailPrice As Decimal = 0

        ' Get the retail price of this product.
        retailPrice = productDataSource.GetRetailPrice(productId)

        Return retailPrice

    End Function

    ''' <summary>The GetWholesalePrice method gets the wholesale price
    ''' for the specified product.</summary>
    ''' <param name="productId">The ID of the product to get the
    ''' wholesale price for.</param>
    ''' <returns>The wholesale price. If there is an error
    ''' the returned price is 0.</returns>
    Public Function GetWholesalePrice(ByVal productId As Integer) As Decimal

        Dim wholesalePrice As Decimal = 0

        ' Get the wholesale price of this product.
        wholesalePrice = productDataSource.GetWholesalePrice(productId)

        Return wholesalePrice
    End Function

    ''' <summary>The Clear method removes all records from
    ''' the product data table.</summary>
    Public Sub Clear()

        ProductDataTable.Clear()

        Exit Sub

    End Sub

    ''' <summary>The SetUpProductData method reads the product data from
    ''' the product information file into a data set that will be used
    ''' while the application is running.</summary>
    ''' <remarks>This method throws an exception on failure.</remarks>
    Public Sub SetupProductData()
        Try

            Dim newDataColumn As System.Data.DataColumn = Nothing

            ' Copy the schema from the xml data.
            productDataSet = productDataSource.GetProductInfo(InvalidProductId)

            ' The product data read from the data file doesn't have a
            ' "current quantity on the drawing" field. Add this column
            ' to the data set.
            newDataColumn = New System.Data.DataColumn(QuantityColumnName, GetType(Integer))
            newDataColumn.DefaultValue = 0
            productDataSet.Tables(0).Columns.Add(newDataColumn)


        Catch ex As Exception

            Dim errWin As ErrorWindow = New ErrorWindow("SetupProductData", ex)
            errWin.ShowDialog()

        End Try
    End Sub

    ''' <summary>The AddProduct method increments the current quantity
    ''' for the specified product. If the productId is not in the table
    ''' the product will be added to the table.</summary>
    ''' <param name="productId">The ID of the product to add.</param>
    Public Sub AddProduct(ByVal productId As Integer)

        Dim productRows As System.Data.DataRow() = Nothing
        Dim productRow As System.Data.DataRow = Nothing
        Dim dataFilter As String

        ' Get the row in the product data table that contains the
        ' product with the specified product id.
        dataFilter = (ProductIdColumnName & " = ") + productId.ToString(System.Globalization.CultureInfo.CurrentCulture)

        ' Query local configuration data for this product ID.
        productRows = ProductDataTable.[Select](dataFilter)

        If productRows.GetUpperBound(0) >= 0 Then
            productRow = productRows(0)
        Else


            ' The productId is not in the table. Add it from the xml data.
            Dim dataSet As System.Data.DataSet
            dataSet = productDataSource.GetProductInfo(productId)
            If (dataSet IsNot Nothing) AndAlso (dataSet.Tables.Count > 0) AndAlso (dataSet.Tables(0).Rows.Count > 0) Then

                ProductDataTable.ImportRow(dataSet.Tables(0).Rows(0))
                productRow = ProductDataTable.[Select](dataFilter)(0)
            End If
        End If

        ' Get the original quantity from the data row and
        ' update the value.
        If productRow IsNot Nothing Then

            Dim quantity As Integer

            quantity = Convert.ToInt16(productRow(QuantityColumnName), System.Globalization.CultureInfo.CurrentCulture)

            quantity += 1

            ' Save the new quantity back into the data row.
            productRow(QuantityColumnName) = quantity

        End If
    End Sub

    ''' <summary>The RemoveProduct method decrements the current quantity for the
    ''' specified product. If the quantity drops to zero the row will be deleted.
    ''' </summary>
    ''' <param name="productId">The ID of the product to remove.</param>
    Public Sub RemoveProduct(ByVal productId As Integer)

        Dim productRows As System.Data.DataRow() = Nothing
        Dim dataFilter As String

        ' Get the row in the product data table that contains the
        ' product with the specified product id.
        dataFilter = (ProductIdColumnName & " = ") + productId.ToString(System.Globalization.CultureInfo.CurrentCulture)
        productRows = ProductDataTable.[Select](dataFilter)

        ' If the productId is not in the table, ignore it.
        If (productRows IsNot Nothing) AndAlso (productRows.GetUpperBound(0) >= 0) Then

            Dim productRow As System.Data.DataRow
            Dim quantity As Integer

            productRow = productRows(0)

            ' Get the original quantity from the data row and
            ' update the value.
            quantity = Convert.ToInt16(productRow(QuantityColumnName), System.Globalization.CultureInfo.CurrentCulture)

            quantity -= 1

            If quantity > 0 Then

                ' Save the new quantity back into the data row.
                productRow(QuantityColumnName) = quantity
            Else

                productRow.Delete()
            End If
        End If
    End Sub

    ''' <summary>The IDisposable::Dispose method cleans up any resources being used.
    ''' </summary>
    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

    ''' <summary>The internal Dispose method does the work to clean up any resources being
    ''' used and is called by the Public Dispose method. This method can only be run once. 
    ''' </summary>
    ''' <param name="disposing">This boolean indicates if the method is being called by the 
    ''' public Dispose method or the destructor.</param>
    Private Sub Dispose(ByVal disposing As Boolean)
        If Not disposed Then
            If disposing Then
                productDataSet.Dispose()
                productDataSource.Dispose()
            End If
        End If
        disposed = True
    End Sub

    ''' <summary>
    ''' Destructor only is called if Dispose method is not called
    ''' </summary>
    Protected Overrides Sub Finalize()
        Try
            Dispose(False)
        Finally
            MyBase.Finalize()
        End Try
    End Sub


End Class

